From ts@uwasa.fi Sun Dec 26 00:00:00 1993 Subject: FAQPAS3.TXT contents Copyright (c) 1993 by Timo Salmi All rights reserved FAQPAS3.TXT The third set of frequently (and not so frequently) asked Turbo Pascal questions with Timo's answers. The items are in no particular order. You are free to quote brief passages from this file provided you clearly indicate the source with a proper acknowledgment. Comments and corrections are solicited. But if you wish to have individual Turbo Pascal consultation, please rather post your questions to a suitable UseNet newsgroup like comp.lang.pascal. It is much more efficient than asking me by email. I'd like to help, but I am very pressed for time. I prefer to pick the questions I answer from the Usenet news. Thus I can answer publicly at one go if I happen to have an answer. Besides, newsgroups have a number of readers who might know a better or an alternative answer. Don't be discouraged, though, if you get a reply like this from me. I am always glad to hear from fellow Turbo Pascal users. .................................................................. Prof. Timo Salmi Co-moderator of comp.archives.msdos.announce Moderating at garbo.uwasa.fi anonymous FTP archives 128.214.87.1 Faculty of Accounting & Industrial Management; University of Vaasa Internet: ts@uwasa.fi BBS +(358)-61-3170972; FIN-65101, Finland ------------------------------------------------------------------- 61) What are Binary Coded Decimals? How to convert them? 62) How can I copy a file in a Turbo Pascal program? 63) How can I use C code in my Turbo Pascal program? 64) How do I get started with the Turbo Profiler? ------------------------------------------------------------------- From ts@uwasa.fi Sun Dec 26 00:01:01 1993 Subject: Binary Coded Decimals 61. ***** Q: What are Binary Coded Decimals? How to convert them? A: Let us look at full integers only and skip the even more difficult question of BCD reals and BCD operations. Decimal Hexa BCD 1 $1 1 : $9 9 10 $A .. : : : 12 $C .. : : : 16 $10 10 17 $11 11 18 $12 12 : : : Consider the last value, that is BCD presentation of 12. The corresponding hexadecimal is $12 (not $C as in normal decimal to hexadecimal conversion). The crucial question is how to convert 12BCD to $12 (or its normal decimal equivalent 18). Here is my sample code: type BCDType = array [0..7] of char; {} procedure StrToBCD (s : string; var b : BCDType); var i, p : byte; begin FillChar(b, SizeOf(b), '0'); p := Length (s); if p > 8 then exit; for i := p downto 1 do b[p-i] := s[i]; end; (* strtobcd *) {} function BCDtoDec (b : BCDType; var ok : boolean) : longint; const Digit : array [0..9] of char = '0123456789'; var i, k : byte; y, d : longint; begin y := 0; d := 1; ok := false; for i := 0 to 7 do begin k := Pos (b[i], Digit); if k = 0 then exit; y := y + (k-1) * d; if i < 7 then d := 16 * d; end; { for } ok := true; BCDtoDec := y; end; (* bcdtodec *) {} {} procedure TEST; var i : byte; b : BCDType; x : longint; ok : boolean; s : string; begin s := '12'; StrToBCD (s, b); write ('The BCD value : '); for i := 7 downto 0 do write (b[i], ' '); writeln; x := BCDtoDec (b, ok); if ok then writeln ('is ', x, ' as an ordinary decimal') else writeln ('Error in BCD'); end; (* test *) {} begin TEST; end. Next we can ask, what if the BCD value is given as an integer. Simple, first convert the integer into a string. For example in the procedure TEST put Str (12, s); Finally, what about converting an ordinary decimal to the corresponding BCD but given also as a decimal variable. For example 18 --> 12? function LHEXFN (decimal : longint) : string; const hexDigit : array [0..15] of char = '0123456789ABCDEF'; var i : byte; s : string; begin FillChar (s, SizeOf(s), ' '); s[0] := chr(8); for i := 0 to 7 do s[8-i] := HexDigit[(decimal shr (4*i)) and $0F]; lhexfn := s; end; (* lhexfn *) {} function DecToBCD (x : longint; var ok : boolean) : longint; const Digit : array [0..9] of char = '0123456789'; var hexStr : string; var i, k : byte; y, d : longint; begin hexStr := LHEXFN(x); y := 0; d := 1; ok := false; for i := 7 downto 0 do begin k := Pos (hexStr[i+1], Digit); if k = 0 then exit; y := y + (k-1) * d; if i > 0 then d := 10 * d; end; { for } ok := true; DecToBCD := y; end; (* dectobcd *) {} procedure TEST2; var i : byte; x10 : longint; xBCD : longint; ok : boolean; begin x10 := 18; writeln ('The ordinary decimal value : ', x10); xBCD := DecToBCD (x10, ok); if ok then writeln ('is ', xBCD, ' as a binary coded decimal') else writeln ('Error in BCD'); end; (* test2 *) {} begin TEST; end. ------------------------------------------------------------------- From ts@uwasa.fi Sun Dec 26 00:01:02 1993 Subject: Copying with TP 62. ***** Q: How can I copy a file in a Turbo Pascal program? A: Here is the code. Take a close look. It has some instructive features besides the copying, like handling the filemode and using dynamic variables (using pointers). procedure SAFECOPY (fromFile, toFile : string); type bufferType = array [1..65535] of char; type bufferTypePtr = ^bufferType; { Use the heap } var bufferPtr : bufferTypePtr; { for the buffer } f1, f2 : file; bufferSize, readCount, writeCount : word; fmSave : byte; { To store the filemode } begin bufferSize := SizeOf(bufferType); if MaxAvail < bufferSize then exit; { Assure there is enough memory } New (bufferPtr); { Create the buffer } fmSave := FileMode; { Store the filemode } FileMode := 0; { To read also read-only files } Assign (f1, fromFile); {$I-} Reset (f1, 1); {$I+} { Note the record size 1, important! } if IOResult <> 0 then exit; { Does the file exist? } Assign (f2, toFile); {$I-} Reset (f2, 1); {$I+} { Don't copy on an existing file } if IOResult = 0 then begin close (f2); exit; end; {$I-} Rewrite (f2, 1); {$I+} { Open the target } if IOResult <> 0 then exit; repeat { Do the copying } BlockRead (f1, bufferPtr^, bufferSize, readCount); {$I-} BlockWrite (f2, bufferPtr^, readCount, writeCount); {$I+} if IOResult <> 0 then begin close (f1); exit; end; until (readCount = 0) or (writeCount <> readCount); writeln ('Copied ', fromFile, ' to ', toFile, ' ', FileSize(f2), ' bytes'); close (f1); close (f2); FileMode := fmSave; { Restore the original filemode } Dispose (bufferPtr); { Release the buffer from the heap } end; (* safecopy *) Of course a trivial solution would be to invoke the MsDos copy command using the Exec routine. (See the item "How do I execute an MsDos command from within a TP program?" ------------------------------------------------------------------ From ts@uwasa.fi Sun Dec 26 00:01:03 1993 Subject: C modules in TP 63. ***** Q: How can I use C code in my Turbo Pascal program? A: I have very little information on this question, since I do not program in C myself. However in reading Turbo Pascal textbooks I have come across a couple of references I can give. They are Edward Mitchell (1993), Borland Pascal Developer's Guide, pp. 60-64, and Stoker & Ohlsen (1989), Turbo Pascal Advanced Techniques, Ch 4. ------------------------------------------------------------------ From ts@uwasa.fi Sun Dec 26 00:01:04 1993 Subject: Using Turbo Profiler 64. ***** Q: How do I get started with the Turbo Profiler? A: Borland's separate Turbo Profiler is a powerful tool for improving program code and enhancing program performance, but far from an easy to use. It is an advanced tool. In fact setting it up the first time is almost a kind of detective work. Let's walk through the steps with Turbo Profiler version 1.01 to see where a running Turbo Pascal program takes its time. Assume a working directory r:\ 1. Copy the target .PAS file to r:\ 2. Compile it with TURBO.EXE using the following Compiler and Debugger options. The standalone debugging option is crucial. Code generation [ ] Force far calls [X] Word align data [ ] Overlays allowed [ ] 286 instructions Runtime errors Syntax options [ ] Range checking [X] Strict var-strings [X] Stack checking [ ] Complete boolean eval [ ] I/O checking [X] Extended syntax [ ] Overflow checking [ ] Typed @ operator [ ] Open parameters Debugging [X] Debug information Numeric processing [X] Local symbols [ ] 8087/80287 [ ] Emulation Debugging Display swapping [X] Integrated ( ) None [X] Standalone () Smart ( ) Always 3) Call TPROF.EXE 4) Load the .EXE file produced by compilation in item 2. 5) Choose from the TPROF menus Statistics Profiling options... Profile mode () Active ( ) Passive Run count 1 Maximum areas 200 6) Choose from the TPROF menus Options Save options... [X] Options [ ] Layout [ ] Macros Save To r:\tfconfig.tf 7) Press Alt-F10 for the Local Menu. Choose Add areas All routines and so on. 8) Choose Run from the TPROF menus (or F9) 9) Choose from the TPROF menus Print Options... Width 80 Height 9999 ( ) Printer ( ) Graphics () File () ASCII Destination File r:\report.lst 10) Print Module... All modules Statistics Overwrite Also see Edward Mitchell (1993), Borland Pascal Developer's Guide. It has a a very instructive chapter "Program Optimization" on the Turbo Profiler. The material in the Turbo Profiler manual is so complicated that additional guidance like Mitchell's is very much needed. ------------------------------------------------------------------